package com.lianrui.app.order.money;

import java.util.Map;

import com.lianrui.app.order.domain.OrderPrice;
import com.lianrui.app.order.money.impl.DefaultCheckout;
import com.lianrui.app.order.money.impl.SelfPackageCheckout;
import com.lianrui.commons.exception.BusinessException;

/**
 * 功能描述：订单结算适配器
 * 
 * @author LJQ
 * 
 * <br>2016年1月15日 上午10:03:30
 */
public abstract class CheckoutAdapter {
	
	public static final String CKOUT_PARAM_CARTS = "carts";
	
	private static CheckoutAdapter instance;
	
	/**
	 * 功能说明：订单价格预处理
	 * @return
	 */
	public OrderPrice before() {
		OrderPrice orderPrice = new OrderPrice();
		return orderPrice;
	}
	
	/**
	 * 功能说明：订单价格后修整
	 * @param orderPrice 订单价格
	 */
	public void affter(OrderPrice orderPrice) {
		
	}

	/**
	 * 功能说明：结算
	 * @param checkout 结算类型
	 * @param params 计算所需参数集合
	 * @return
	 * @throws BusinessException 
	 */
	public synchronized static OrderPrice checkout(Checkout checkout, Map<String, Object> params) throws BusinessException {
		OrderPrice orderPrice = getInstance().before();
		
		checkout.getCheckout().setParams(params);
		checkout.getCheckout().onCheckout(orderPrice);
		
		getInstance().affter(orderPrice);
		
		return orderPrice;
	}
	
	/**
	 * 功能说明：单例模式
	 * @return
	 */
	public synchronized static final CheckoutAdapter getInstance() {
		if (instance == null) {
			instance = new CheckoutAdapter(){};
		}
		return instance;
	}
	
	/**
	 * 功能描述：结算枚举类
	 * 
	 * @author LJQ
	 * 
	 * <br>2016年1月15日 下午3:59:30
	 */
	public enum Checkout {
		/**
		 * 功能描述：默认-结算方式
		 */
		Default {
			public ICheckout getCheckout() {
				return new DefaultCheckout();
			}
		},
		/**
		 * 功能描述：直接购买-结算方式
		 */
		Product {
			public ICheckout getCheckout() {
				return new DefaultCheckout();
			}
		},
		/**
		 * 功能描述：绑定套餐-结算方式
		 */
		BindingPackage {
			public ICheckout getCheckout() {
				return new DefaultCheckout();
			}
		},
		/**
		 * 功能描述：自选套餐-结算方式
		 */
		SelfPackage {
			public ICheckout getCheckout() {
				return new SelfPackageCheckout();
			}
		};
		
		/**
		 * 功能说明：获取结算方式
		 */
		protected abstract ICheckout getCheckout();
	}
	
}
